<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">

<title>class Fiber::Scheduler - RDoc Documentation</title>


<script src="../js/navigation.js" defer></script>
<script src="../js/search.js" defer></script>
<script src="../js/search_index.js" defer></script>
<script src="../js/searcher.js" defer></script>
<script src="../js/darkfish.js" defer></script>

<script src="../js/jquery-3.2.0.min.js"></script>

<script src="../js/vue.min.js"></script>
<script src="../js/js.cookie.min.js"></script>

<link href="../css/fonts.css" rel="stylesheet">
<link id='rdoccss' href="../css/rdoc.css" rel="stylesheet">
<link href="../css/carbon17.css" rel="stylesheet">

<script type="text/javascript">
  var rdoc_rel_prefix = "../";
  var index_rel_prefix = "../";
  var darkModeCsseHref = "../css/rdoc-dm.css"
  var defaultModeCssHref = "../css/rdoc.css"
  // var cssDarkmode = Cookies.get('darkmode');
  
  if( Cookies.get("darkmode") == "true") {
	$('#rdoccss').attr("href", darkModeCsseHref);
}

//  https://cssdeck.com/blog/simple-jquery-stylesheet-switcher/

document.write('<style type="text/css">body{display:none}</style>');

</script>


</head>
<body id="top" role="document" class="class">
  <!-- this is class.html -->

  <div id='actionbar' >
    <div class='wrapper mdiv'>
      <ul class='grids g0'></ul>
    </div> 
    <!-- VERSION HEADER for 3.3.0-preview2 NOT FOUND -->
  </div> <!-- end action bar -->

  <div class='wrapper hdiv'>

    


    <nav id='vapp' role="navigation">
    <div id="project-navigation">
      <div id="home-section" role="region" title="Quick navigation" class="nav-section">
  <h2><a href="../index.html" rel="home">Home</a></h2>

  <div id="table-of-contents-navigation"  >
    <a href="../table_of_contents.html#pages">Pages</a>
    <a href="../table_of_contents.html#classes">Classes</a>
    <a href="../table_of_contents.html#methods">Methods</a>
  </div>
</div>

      <div id="search-section" role="search" class="project-section initially-hidden">
  <form action="#" method="get" accept-charset="utf-8">
    <div id="search-field-wrapper">
      <input id="search-field" role="combobox" aria-label="Search"
             aria-autocomplete="list" aria-controls="search-results"
             type="text" name="search" placeholder="Search" spellcheck="false"
             title="Type to search, Up and Down to navigate, Enter to load">
    </div>

    <ul id="search-results" aria-label="Search Results"
        aria-busy="false" aria-expanded="false"
        aria-atomic="false" class="initially-hidden"></ul>
  </form>
</div>

    </div>


    

    <button id='toggleThing' @click="toggleNav()" >Show/hide navigation</button>
    <div :class="isOpen ? 'block' : 'hidden' " id='toggleMe'>
      <div id="class-metadata">
        
        
<div id="parent-class-section" class="nav-section">
  <h3>Parent</h3>

  <p class="link"><a href="../Object.html">Object</a>
</div>

        
        
        
<!-- Method Quickref -->
<div id="method-list-section" class="nav-section">
  <h3>Methods</h3>

  <ul class="link-list" role="directory">
    <li ><a href="#method-i-address_resolve">#address_resolve</a>
    <li ><a href="#method-i-block">#block</a>
    <li ><a href="#method-i-close">#close</a>
    <li ><a href="#method-i-fiber">#fiber</a>
    <li ><a href="#method-i-io_pread">#io_pread</a>
    <li ><a href="#method-i-io_pwrite">#io_pwrite</a>
    <li ><a href="#method-i-io_read">#io_read</a>
    <li ><a href="#method-i-io_select">#io_select</a>
    <li ><a href="#method-i-io_wait">#io_wait</a>
    <li ><a href="#method-i-io_write">#io_write</a>
    <li ><a href="#method-i-kernel_sleep">#kernel_sleep</a>
    <li ><a href="#method-i-process_wait">#process_wait</a>
    <li ><a href="#method-i-timeout_after">#timeout_after</a>
    <li ><a href="#method-i-unblock">#unblock</a>
  </ul>
</div>

      </div>
     </div>
    </nav>


    <div id='extraz'><div class='adzbox-index'  >
      
     </div>         
    </div>

    <main role="main" aria-labelledby="class-Fiber::Scheduler">
    <h1 id="class-Fiber::Scheduler" class="class">
      class Fiber::Scheduler
    </h1>

    <section class="description">
    
<p>This is not an existing class, but documentation of the interface that <a href="Scheduler.html"><code>Scheduler</code></a> object should comply to in order to be used as argument to <a href="../Fiber.html#method-c-scheduler"><code>Fiber.scheduler</code></a> and handle non-blocking fibers. See also the “Non-blocking fibers” section in <a href="../Fiber.html"><code>Fiber</code></a> class docs for explanations of some concepts.</p>

<p>Scheduler’s behavior and usage are expected to be as follows:</p>
<ul><li>
<p>When the execution in the non-blocking <a href="../Fiber.html"><code>Fiber</code></a> reaches some blocking operation (like sleep, wait for a process, or a non-ready I/O), it calls some of the scheduler’s hook methods, listed below.</p>
</li><li>
<p><a href="Scheduler.html"><code>Scheduler</code></a> somehow registers what the current fiber is waiting on, and yields control to other fibers with <a href="../Fiber.html#method-c-yield"><code>Fiber.yield</code></a> (so the fiber would be suspended while expecting its wait to end, and other fibers in the same thread can perform)</p>
</li><li>
<p>At the end of the current thread execution, the scheduler’s method scheduler_close is called</p>
</li><li>
<p>The scheduler runs into a wait loop, checking all the blocked fibers (which it has registered on hook calls) and resuming them when the awaited resource is ready (e.g. I/O ready or sleep time elapsed).</p>
</li></ul>

<p>This way concurrent execution will be achieved transparently for every individual Fiber’s code.</p>

<p><a href="Scheduler.html"><code>Scheduler</code></a> implementations are provided by gems, like <a href="https://github.com/socketry/async">Async</a>.</p>

<p>Hook methods are:</p>
<ul><li>
<p><a href="Scheduler.html#method-i-io_wait"><code>io_wait</code></a>, <a href="Scheduler.html#method-i-io_read"><code>io_read</code></a>, <a href="Scheduler.html#method-i-io_write"><code>io_write</code></a>, <a href="Scheduler.html#method-i-io_pread"><code>io_pread</code></a>, <a href="Scheduler.html#method-i-io_pwrite"><code>io_pwrite</code></a>, and <a href="Scheduler.html#method-i-io_select"><code>io_select</code></a>, io_close</p>
</li><li>
<p><a href="Scheduler.html#method-i-process_wait"><code>process_wait</code></a></p>
</li><li>
<p><a href="Scheduler.html#method-i-kernel_sleep"><code>kernel_sleep</code></a></p>
</li><li>
<p><a href="Scheduler.html#method-i-timeout_after"><code>timeout_after</code></a></p>
</li><li>
<p><a href="Scheduler.html#method-i-address_resolve"><code>address_resolve</code></a></p>
</li><li>
<p><a href="Scheduler.html#method-i-block"><code>block</code></a> and <a href="Scheduler.html#method-i-unblock"><code>unblock</code></a></p>
</li><li>
<p>(the list is expanded as Ruby developers make more methods having non-blocking calls)</p>
</li></ul>

<p>When not specified otherwise, the hook implementations are mandatory: if they are not implemented, the methods trying to call hook will fail. To provide backward compatibility, in the future hooks will be optional (if they are not implemented, due to the scheduler being created for the older Ruby version, the code which needs this hook will not fail, and will just behave in a blocking fashion).</p>

<p>It is also strongly recommended that the scheduler implements the <a href="Scheduler.html#method-i-fiber"><code>fiber</code></a> method, which is delegated to by <a href="../Fiber.html#method-c-schedule"><code>Fiber.schedule</code></a>.</p>

<p>Sample <em>toy</em> implementation of the scheduler can be found in Ruby’s code, in <code>test/fiber/scheduler.rb</code></p>

    </section>

      <section id="5Buntitled-5D" class="documentation-section">





                <section id="public-instance-5Buntitled-5D-method-details" class="method-section">
                <header>
                <h3>Public Instance Methods</h3>
                </header>

                  <div id="method-i-address_resolve" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          address_resolve(hostname) &rarr; array_of_strings or nil
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Invoked by any method that performs a non-reverse DNS lookup. The most notable method is Addrinfo.getaddrinfo, but there are many other.</p>

<p>The method is expected to return an array of strings corresponding to ip addresses the <code>hostname</code> is resolved to, or <code>nil</code> if it can not be resolved.</p>

<p>Fairly exhaustive list of all possible call-sites:</p>
<ul><li>
<p>Addrinfo.getaddrinfo</p>
</li><li>
<p>Addrinfo.tcp</p>
</li><li>
<p>Addrinfo.udp</p>
</li><li>
<p>Addrinfo.ip</p>
</li><li>
<p>Addrinfo.new</p>
</li><li>
<p>Addrinfo.marshal_load</p>
</li><li>
<p>SOCKSSocket.new</p>
</li><li>
<p>TCPServer.new</p>
</li><li>
<p>TCPSocket.new</p>
</li><li>
<p>IPSocket.getaddress</p>
</li><li>
<p>TCPSocket.gethostbyname</p>
</li><li>
<p>UDPSocket#connect</p>
</li><li>
<p>UDPSocket#bind</p>
</li><li>
<p>UDPSocket#send</p>
</li><li>
<p>Socket.getaddrinfo</p>
</li><li>
<p>Socket.gethostbyname</p>
</li><li>
<p>Socket.pack_sockaddr_in</p>
</li><li>
<p>Socket.sockaddr_in</p>
</li><li>
<p>Socket.unpack_sockaddr_in</p>
</li></ul>

                              <div class="method-source-code" id="address_resolve-source">
            <pre>VALUE
rb_fiber_scheduler_address_resolve(VALUE scheduler, VALUE hostname)
{
    VALUE arguments[] = {
        hostname
    };

    return rb_check_funcall(scheduler, id_address_resolve, 1, arguments);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-block" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          block(blocker, timeout = nil)
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Invoked by methods like <a href="../Thread.html#method-i-join"><code>Thread.join</code></a>, and by Mutex, to signify that current <a href="../Fiber.html"><code>Fiber</code></a> is blocked until further notice (e.g. <a href="Scheduler.html#method-i-unblock"><code>unblock</code></a>) or until <code>timeout</code> has elapsed.</p>

<p><code>blocker</code> is what we are waiting on, informational only (for debugging and logging). There are no guarantee about its value.</p>

<p>Expected to return boolean, specifying whether the blocking operation was successful or not.</p>

                              <div class="method-source-code" id="block-source">
            <pre>VALUE
rb_fiber_scheduler_block(VALUE scheduler, VALUE blocker, VALUE timeout)
{
    return rb_funcall(scheduler, id_block, 2, blocker, timeout);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-close" class="method-detail ">
                            <div class="method-heading">
                              <span class="method-name">close</span><span
                                class="method-args">()</span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Called when the current thread exits. The scheduler is expected to implement this method in order to allow all waiting fibers to finalize their execution.</p>

<p>The suggested pattern is to implement the main event loop in the <a href="Scheduler.html#method-i-close"><code>close</code></a> method.</p>

                              <div class="method-source-code" id="close-source">
            <pre>VALUE
rb_fiber_scheduler_close(VALUE scheduler)
{
    VM_ASSERT(ruby_thread_has_gvl_p());

    VALUE result;

    // The reason for calling `scheduler_close` before calling `close` is for
    // legacy schedulers which implement `close` and expect the user to call
    // it. Subsequently, that method would call `Fiber.set_scheduler(nil)`
    // which should call `scheduler_close`. If it were to call `close`, it
    // would create an infinite loop.

    result = rb_check_funcall(scheduler, id_scheduler_close, 0, NULL);
    if (!UNDEF_P(result)) return result;

    result = rb_check_funcall(scheduler, id_close, 0, NULL);
    if (!UNDEF_P(result)) return result;

    return Qnil;
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-fiber" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          fiber(&amp;block)
                              </span>
                            </div>

                            <div class="method-description">
                              <p>Implementation of the <a href="../Fiber.html#method-c-schedule"><code>Fiber.schedule</code></a>. The method is <em>expected</em> to immediately run the given block of code in a separate non-blocking fiber, and to return that <a href="../Fiber.html"><code>Fiber</code></a>.</p>

<p>Minimal suggested implementation is:</p>

<pre class="ruby"><span class="ruby-keyword">def</span> <span class="ruby-identifier ruby-title">fiber</span>(<span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span>)
  <span class="ruby-identifier">fiber</span> = <span class="ruby-constant">Fiber</span>.<span class="ruby-identifier">new</span>(<span class="ruby-value">blocking:</span> <span class="ruby-keyword">false</span>, <span class="ruby-operator">&amp;</span><span class="ruby-identifier">block</span>)
  <span class="ruby-identifier">fiber</span>.<span class="ruby-identifier">resume</span>
  <span class="ruby-identifier">fiber</span>
<span class="ruby-keyword">end</span>
</pre>

                            </div>


                          </div>

                  <div id="method-i-io_pread" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          io_pread(io, buffer, from, length, offset) &rarr; read length or -errno
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Invoked by <a href="../IO.html#method-i-pread"><code>IO#pread</code></a> or <a href="../IO/Buffer.html#method-i-pread"><code>IO::Buffer#pread</code></a> to read <code>length</code> bytes from <code>io</code> at offset <code>from</code> into a specified <code>buffer</code> (see <a href="../IO/Buffer.html"><code>IO::Buffer</code></a>) at the given <code>offset</code>.</p>

<p>This method is semantically the same as <a href="Scheduler.html#method-i-io_read"><code>io_read</code></a>, but it allows to specify the offset to read from and is often better for asynchronous <a href="../IO.html"><code>IO</code></a> on the same file.</p>

<p>The method should be considered <em>experimental</em>.</p>

                              <div class="method-source-code" id="io_pread-source">
            <pre>VALUE
rb_fiber_scheduler_io_pread(VALUE scheduler, VALUE io, rb_off_t from, VALUE buffer, size_t length, size_t offset)
{
    VALUE arguments[] = {
        io, buffer, OFFT2NUM(from), SIZET2NUM(length), SIZET2NUM(offset)
    };

    return rb_check_funcall(scheduler, id_io_pread, 5, arguments);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-io_pwrite" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          io_pwrite(io, buffer, from, length, offset) &rarr; written length or -errno
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Invoked by <a href="../IO.html#method-i-pwrite"><code>IO#pwrite</code></a> or <a href="../IO/Buffer.html#method-i-pwrite"><code>IO::Buffer#pwrite</code></a> to write <code>length</code> bytes to <code>io</code> at offset <code>from</code> into a specified <code>buffer</code> (see <a href="../IO/Buffer.html"><code>IO::Buffer</code></a>) at the given <code>offset</code>.</p>

<p>This method is semantically the same as <a href="Scheduler.html#method-i-io_write"><code>io_write</code></a>, but it allows to specify the offset to write to and is often better for asynchronous <a href="../IO.html"><code>IO</code></a> on the same file.</p>

<p>The method should be considered <em>experimental</em>.</p>

                              <div class="method-source-code" id="io_pwrite-source">
            <pre>VALUE
rb_fiber_scheduler_io_pwrite(VALUE scheduler, VALUE io, rb_off_t from, VALUE buffer, size_t length, size_t offset)
{
    VALUE arguments[] = {
        io, buffer, OFFT2NUM(from), SIZET2NUM(length), SIZET2NUM(offset)
    };

    return rb_check_funcall(scheduler, id_io_pwrite, 5, arguments);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-io_read" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          io_read(io, buffer, length, offset) &rarr; read length or -errno
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Invoked by <a href="../IO.html#method-i-read"><code>IO#read</code></a> or IO#Buffer.read to read <code>length</code> bytes from <code>io</code> into a specified <code>buffer</code> (see <a href="../IO/Buffer.html"><code>IO::Buffer</code></a>) at the given <code>offset</code>.</p>

<p>The <code>length</code> argument is the “minimum length to be read”. If the <a href="../IO.html"><code>IO</code></a> buffer size is 8KiB, but the <code>length</code> is <code>1024</code> (1KiB), up to 8KiB might be read, but at least 1KiB will be. Generally, the only case where less data than <code>length</code> will be read is if there is an error reading the data.</p>

<p>Specifying a <code>length</code> of 0 is valid and means try reading at least once and return any available data.</p>

<p>Suggested implementation should try to read from <code>io</code> in a non-blocking manner and call <a href="Scheduler.html#method-i-io_wait"><code>io_wait</code></a> if the <code>io</code> is not ready (which will yield control to other fibers).</p>

<p>See <a href="../IO/Buffer.html"><code>IO::Buffer</code></a> for an interface available to return data.</p>

<p>Expected to return number of bytes read, or, in case of an error, <code>-errno</code> (negated number corresponding to system’s error code).</p>

<p>The method should be considered <em>experimental</em>.</p>

                              <div class="method-source-code" id="io_read-source">
            <pre>VALUE
rb_fiber_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t length, size_t offset)
{
    VALUE arguments[] = {
        io, buffer, SIZET2NUM(length), SIZET2NUM(offset)
    };

    return rb_check_funcall(scheduler, id_io_read, 4, arguments);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-io_select" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          io_select(readables, writables, exceptables, timeout)
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Invoked by <a href="../IO.html#method-c-select"><code>IO.select</code></a> to ask whether the specified descriptors are ready for specified events within the specified <code>timeout</code>.</p>

<p>Expected to return the 3-tuple of <a href="../Array.html"><code>Array</code></a> of IOs that are ready.</p>

                              <div class="method-source-code" id="io_select-source">
            <pre>VALUE rb_fiber_scheduler_io_select(VALUE scheduler, VALUE readables, VALUE writables, VALUE exceptables, VALUE timeout)
{
    VALUE arguments[] = {
        readables, writables, exceptables, timeout
    };

    return rb_fiber_scheduler_io_selectv(scheduler, 4, arguments);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-io_wait" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          io_wait(io, events, timeout)
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Invoked by <a href="../IO.html#method-i-wait"><code>IO#wait</code></a>, <a href="../IO.html#method-i-wait_readable"><code>IO#wait_readable</code></a>, <a href="../IO.html#method-i-wait_writable"><code>IO#wait_writable</code></a> to ask whether the specified descriptor is ready for specified events within the specified <code>timeout</code>.</p>

<p><code>events</code> is a bit mask of <code>IO::READABLE</code>, <code>IO::WRITABLE</code>, and <code>IO::PRIORITY</code>.</p>

<p>Suggested implementation should register which <a href="../Fiber.html"><code>Fiber</code></a> is waiting for which resources and immediately calling <a href="../Fiber.html#method-c-yield"><code>Fiber.yield</code></a> to pass control to other fibers. Then, in the <a href="Scheduler.html#method-i-close"><code>close</code></a> method, the scheduler might dispatch all the I/O resources to fibers waiting for it.</p>

<p>Expected to return the subset of events that are ready immediately.</p>

                              <div class="method-source-code" id="io_wait-source">
            <pre>VALUE
rb_fiber_scheduler_io_wait(VALUE scheduler, VALUE io, VALUE events, VALUE timeout)
{
    return rb_funcall(scheduler, id_io_wait, 3, io, events, timeout);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-io_write" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          io_write(io, buffer, length, offset) &rarr; written length or -errno
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Invoked by <a href="../IO.html#method-i-write"><code>IO#write</code></a> or <a href="../IO/Buffer.html#method-i-write"><code>IO::Buffer#write</code></a> to write <code>length</code> bytes to <code>io</code> from from a specified <code>buffer</code> (see <a href="../IO/Buffer.html"><code>IO::Buffer</code></a>) at the given <code>offset</code>.</p>

<p>The <code>length</code> argument is the “minimum length to be written”. If the <a href="../IO.html"><code>IO</code></a> buffer size is 8KiB, but the <code>length</code> specified is 1024 (1KiB), at most 8KiB will be written, but at least 1KiB will be. Generally, the only case where less data than <code>length</code> will be written is if there is an error writing the data.</p>

<p>Specifying a <code>length</code> of 0 is valid and means try writing at least once, as much data as possible.</p>

<p>Suggested implementation should try to write to <code>io</code> in a non-blocking manner and call <a href="Scheduler.html#method-i-io_wait"><code>io_wait</code></a> if the <code>io</code> is not ready (which will yield control to other fibers).</p>

<p>See <a href="../IO/Buffer.html"><code>IO::Buffer</code></a> for an interface available to get data from buffer efficiently.</p>

<p>Expected to return number of bytes written, or, in case of an error, <code>-errno</code> (negated number corresponding to system’s error code).</p>

<p>The method should be considered <em>experimental</em>.</p>

                              <div class="method-source-code" id="io_write-source">
            <pre>VALUE
rb_fiber_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t length, size_t offset)
{
    VALUE arguments[] = {
        io, buffer, SIZET2NUM(length), SIZET2NUM(offset)
    };

    return rb_check_funcall(scheduler, id_io_write, 4, arguments);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-kernel_sleep" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          kernel_sleep(duration = nil)
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Invoked by <a href="../Kernel.html#method-i-sleep"><code>Kernel#sleep</code></a> and Mutex#sleep and is expected to provide an implementation of sleeping in a non-blocking way. Implementation might register the current fiber in some list of “which fiber wait until what moment”, call <a href="../Fiber.html#method-c-yield"><code>Fiber.yield</code></a> to pass control, and then in <a href="Scheduler.html#method-i-close"><code>close</code></a> resume the fibers whose wait period has elapsed.</p>

                              <div class="method-source-code" id="kernel_sleep-source">
            <pre>VALUE
rb_fiber_scheduler_kernel_sleep(VALUE scheduler, VALUE timeout)
{
    return rb_funcall(scheduler, id_kernel_sleep, 1, timeout);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-process_wait" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          process_wait(pid, flags)
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Invoked by <a href="../Process/Status.html#method-c-wait"><code>Process::Status.wait</code></a> in order to wait for a specified process. See that method description for arguments description.</p>

<p>Suggested minimal implementation:</p>

<pre class="ruby"><span class="ruby-constant">Thread</span>.<span class="ruby-identifier">new</span> <span class="ruby-keyword">do</span>
  <span class="ruby-constant">Process</span><span class="ruby-operator">::</span><span class="ruby-constant">Status</span>.<span class="ruby-identifier">wait</span>(<span class="ruby-identifier">pid</span>, <span class="ruby-identifier">flags</span>)
<span class="ruby-keyword">end</span>.<span class="ruby-identifier">value</span>
</pre>

<p>This hook is optional: if it is not present in the current scheduler, <a href="../Process/Status.html#method-c-wait"><code>Process::Status.wait</code></a> will behave as a blocking method.</p>

<p>Expected to return a <a href="../Process/Status.html"><code>Process::Status</code></a> instance.</p>

                              <div class="method-source-code" id="process_wait-source">
            <pre>VALUE
rb_fiber_scheduler_process_wait(VALUE scheduler, rb_pid_t pid, int flags)
{
    VALUE arguments[] = {
        PIDT2NUM(pid), RB_INT2NUM(flags)
    };

    return rb_check_funcall(scheduler, id_process_wait, 2, arguments);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-timeout_after" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          timeout_after(duration, exception_class, *exception_arguments, &amp;block) &rarr; result of block
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Invoked by Timeout.timeout to execute the given <code>block</code> within the given <code>duration</code>. It can also be invoked directly by the scheduler or user code.</p>

<p>Attempt to limit the execution time of a given <code>block</code> to the given <code>duration</code> if possible. When a non-blocking operation causes the <code>block</code>‘s execution time to exceed the specified <code>duration</code>, that non-blocking operation should be interrupted by raising the specified <code>exception_class</code> constructed with the given <code>exception_arguments</code>.</p>

<p>General execution timeouts are often considered risky. This implementation will only interrupt non-blocking operations. This is by design because it’s expected that non-blocking operations can fail for a variety of unpredictable reasons, so applications should already be robust in handling these conditions and by implication timeouts.</p>

<p>However, as a result of this design, if the <code>block</code> does not invoke any non-blocking operations, it will be impossible to interrupt it. If you desire to provide predictable points for timeouts, consider adding +sleep(0)+.</p>

<p>If the block is executed successfully, its result will be returned.</p>

<p>The exception will typically be raised using <a href="../Fiber.html#method-i-raise"><code>Fiber#raise</code></a>.</p>

                              <div class="method-source-code" id="timeout_after-source">
            <pre>VALUE
rb_fiber_scheduler_timeout_after(VALUE scheduler, VALUE timeout, VALUE exception, VALUE message)
{
    VALUE arguments[] = {
        timeout, exception, message
    };

    return rb_check_funcall(scheduler, id_timeout_after, 3, arguments);
}</pre>
                              </div>
                            </div>


                          </div>

                  <div id="method-i-unblock" class="method-detail ">
                      <div class="method-heading">
                        <span class="method-callseq">
                          unblock(blocker, fiber)
                              </span>
                              <span class="method-click-advice">click to toggle source</span>
                            </div>

                            <div class="method-description">
                              <p>Invoked to wake up <a href="../Fiber.html"><code>Fiber</code></a> previously blocked with <a href="Scheduler.html#method-i-block"><code>block</code></a> (for example, Mutex#lock calls <a href="Scheduler.html#method-i-block"><code>block</code></a> and Mutex#unlock calls <a href="Scheduler.html#method-i-unblock"><code>unblock</code></a>). The scheduler should use the <code>fiber</code> parameter to understand which fiber is unblocked.</p>

<p><code>blocker</code> is what was awaited for, but it is informational only (for debugging and logging), and it is not guaranteed to be the same value as the <code>blocker</code> for <a href="Scheduler.html#method-i-block"><code>block</code></a>.</p>

                              <div class="method-source-code" id="unblock-source">
            <pre>VALUE
rb_fiber_scheduler_unblock(VALUE scheduler, VALUE blocker, VALUE fiber)
{
    VM_ASSERT(rb_obj_is_fiber(fiber));

    return rb_funcall(scheduler, id_unblock, 2, blocker, fiber);
}</pre>
                              </div>
                            </div>


                          </div>

                          </section>

              </section>
              </main>



            </div>  <!--  class='wrapper hdiv' -->


<footer id="validator-badges" role="contentinfo">
<p><a href="https://validator.w3.org/check/referer">Validate</a></p>
<p>Generated by <a href="https://ruby.github.io/rdoc/">RDoc</a> 6.4.0.</p>
<p>Based on <a href="https://github.com/ged/darkfish/">Darkfish</a> by <a href="http://deveiate.org">Michael Granger</a>.</p>

  
    <p><p><a href="https://ruby-doc.org">Ruby-doc.org</a> is provided by <a href="https://jamesbritt.com">James Britt</a> and <a href="https://neurogami.com">Neurogami</a>.</p><p><a href="https://jamesbritt.bandcamp.com/">Maximum R+D</a>.  </p>
</p>
  
  </footer>

<script type="text/javascript">


  let ads  = $("#carbonads-container").children().detach();


  function swapMode() {
    var cookieName = 'darkmode';
    var cssDarkmode = Cookies.get(cookieName);
    console.log("***** swapMode! " + cssDarkmode + " *****");


    if (cssDarkmode == "true") {
      console.log("We have dark mode, set the css to light ...");
      $('#rdoccss').attr("href", defaultModeCssHref);
      $('#cssSelect').text("Dark mode");
      cssDarkmode = "false";
      console.log("swapMode! Now set cookie to " + cssDarkmode);
      Cookies.set(cookieName, cssDarkmode);

    } else {
      console.log("We not have dark mode, set the css to dark ...");
      $('#rdoccss').attr("href", darkModeCsseHref);
      $('#cssSelect').text("Light mode");
      cssDarkmode = "true";
      console.log("swapMode! Now set cookie to " + cssDarkmode);
      Cookies.set(cookieName, cssDarkmode);

    }

    console.log("  --------------- ");
  }


const vueCssApp = new Vue({
el: '#menubar',
data: {
isDark: false
},
methods: {
toggleClass: function(event){
this.isDark = !this.isDark;
}
}
})

const vueApp = new Vue({
el: '#vapp',
data: { 
isOpen: true
},

mounted() {
this.handleResize();
this.manage_mob_classes();
window.addEventListener('resize', this.handleResize)
//this.isOpen !=  (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
},
destroyed() {
window.removeEventListener('resize', this.handleResize)
},
created() {
//manage_mob_classes();
},

methods : {
isMobile() {
  return (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
},

  handleResize() {
    if (!this.isMobile()) {
      this.isOpen = window.innerWidth > 800;
    }
  },

  manage_mob_classes() {
    if (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)) {
      $("nav").addClass("mob_nav");
      $("main").addClass("mob_main");
      $("#extraz").addClass("mob_extraz");
      $("#carbonads-container").addClass("mob_carbonads-container");
      this.isOpen  = false;
    } else {
      $("nav").removeClass("mob_nav") 
        $("main").removeClass("mob_main");
      $("#extraz").removeClass("mob_extraz");
      $("#carbonads-container").removeClass("mob_carbonads-container");
      this.isOpen  = true;
    }
  },

  toggleNav() {
    this.isOpen =! this.isOpen ;
    // alert("Toggle nav!");
    console.log("toggleNav() click: " + this.isOpen );
  }
}
})

$("#carbonads-container").append(ads);


$(function() {

    var darkmode = Cookies.get("darkmode");
    console.log("Document ready: " + darkmode);

    if ( darkmode  == "true" ) {
      $('#cssSelect').text("Light mode");
    } else {
      $('#cssSelect').text("Dark mode");
     }

    $('body').css('display','block');
    });

</script>

    
  </body> 
</html>

